package com.yanhuo.search.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yanhuo.common.exception.YanHuoException;
import com.yanhuo.common.utils.ConvertUtils;
import com.yanhuo.common.utils.PageUtils;
import com.yanhuo.common.utils.RedisUtils;
import com.yanhuo.platform.service.impl.CategoryServiceImpl;
import com.yanhuo.platform.service.impl.TagNoteRelationServiceImpl;
import com.yanhuo.platform.service.impl.TagServiceImpl;
import com.yanhuo.platform.service.impl.UserServiceImpl;
import com.yanhuo.search.common.NoteConstant;
import com.yanhuo.search.dto.NoteDTO;
import com.yanhuo.search.service.esNoteService;
import com.yanhuo.xo.dao.NoteDao;
import com.yanhuo.xo.entity.*;
import com.yanhuo.xo.vo.NoteSearchVo;
import jodd.util.ComparableComparator;
import lombok.extern.slf4j.Slf4j;
import org.junit.platform.commons.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author xiaozhao
 */
@Service
@Slf4j
public class esNoteServiceImpl extends ServiceImpl<NoteDao, Note> implements esNoteService {


//    @Autowired
//    ElasticsearchClient elasticsearchClient;

    @Autowired
    UserServiceImpl userService;

    @Autowired
    TagNoteRelationServiceImpl tagNoteRelationService;

    @Autowired
    TagServiceImpl tagService;

    @Autowired
    CategoryServiceImpl categoryService;

    @Autowired
    RedisUtils redisUtils;


    @Override
    public Page<NoteSearchVo> getNotePageByDTO(long currentPage, long pageSize, NoteDTO noteDTO) {
        Page<NoteSearchVo> page ;
        List<NoteSearchVo> noteSearchVoList = new ArrayList<>();
        String cid=noteDTO.getCid();
        String cpid=noteDTO.getCpid();
        try {
            List<String> list = redisUtils.lRange(NoteConstant.NOTE_INDEX, 0, -1);
            for (String noteSearchVo : list) {
                noteSearchVoList.add(JSON.parseObject(noteSearchVo, NoteSearchVo.class));
            }
            String k=noteDTO.getKeyword();
            if(noteDTO.getKeyword()!=null&& StringUtils.isNotBlank(noteDTO.getKeyword())){
                System.out.println("搜索+keyword");
               noteSearchVoList= noteSearchVoList.stream().filter(e->e.getCategoryName().contains(k)||e.getContent().contains(k)||e.getCategoryParentName().contains(k)||e.getTitle().contains(k)).collect(Collectors.toList());
            }
            else if (cid!=null&&cpid!=null&&StringUtils.isNotBlank(noteDTO.getCpid()) && StringUtils.isNotBlank(noteDTO.getCid())) {
                System.out.println("搜索+cpid+cid");
                noteSearchVoList=noteSearchVoList.stream().filter(e->e.getCid().contains(cid)||e.getCpid().contains(cpid)).collect(Collectors.toList());
            } else if (cpid!=null&&StringUtils.isNotBlank(noteDTO.getCpid())) {
                System.out.println("搜索+cpid");
                noteSearchVoList=noteSearchVoList.stream().filter(e->e.getCpid().contains(cpid)).collect(Collectors.toList());
            }

           else if (noteDTO.getType()!=null&&noteDTO.getType() == 1) {
                System.out.println("搜索+like");
                noteSearchVoList=noteSearchVoList.stream().sorted( Comparator.comparing(NoteSearchVo::getLikeCount).reversed()).collect(Collectors.toList());
            } else if (noteDTO.getType()!=null&&noteDTO.getType() == 2) {
                System.out.println("搜索+time");
                noteSearchVoList=noteSearchVoList.stream().sorted( Comparator.comparing(NoteSearchVo::getTime).reversed()).collect(Collectors.toList());
            }

        } catch (Exception e) {
            throw new YanHuoException("redis查找数据异常");
        }
        page=PageUtils.getPages((int)currentPage,(int)pageSize,noteSearchVoList);
        return page;
    }


    @Override
    public Page<NoteSearchVo> getRecommendNotePage(long currentPage, long pageSize) {
        Page<NoteSearchVo> page = new Page<>();
        List<NoteSearchVo> noteSearchVoList = new ArrayList<NoteSearchVo>();
        List<String> list = redisUtils.lRange(NoteConstant.NOTE_INDEX, 0, -1);
        for (String noteSearchVo : list) {
            noteSearchVoList.add(JSON.parseObject(noteSearchVo, NoteSearchVo.class));
        }
        Collections.shuffle(noteSearchVoList);
        page = PageUtils.getPages((int) currentPage, (int) pageSize, noteSearchVoList);
        return page;
    }

    @Override
    public void addNote(NoteSearchVo noteSearchVo) {
        try {
//            CreateResponse createResponse = elasticsearchClient.create(e -> e.index(NoteConstant.NOTE_INDEX).id(noteSearchVo.getId()).document(noteSearchVo));
//            log.info("createResponse.result{}", createResponse.result());
            redisUtils.lLeftPush(NoteConstant.NOTE_INDEX, JSON.toJSONString(noteSearchVo));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void updateNote(NoteSearchVo noteSearchVo) {
        try {
            this.deleteNote(noteSearchVo.getId());
            redisUtils.lLeftPush(NoteConstant.NOTE_INDEX,JSON.toJSONString(noteSearchVo));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void addNoteBulkData(List<NoteSearchVo> noteSearchVoList) {
        try {
//            List<BulkOperation> result = new ArrayList<>();
//            for (NoteSearchVo noteSearchVo : noteSearchVoList) {
//                result.add(new BulkOperation.Builder().create(
//                        d -> d.document(noteSearchVo).id(noteSearchVo.getId()).index(NoteConstant.NOTE_INDEX)).build());
//            }
//            BulkResponse bulkResponse = elasticsearchClient.bulk(e -> e.index(NoteConstant.NOTE_INDEX).operations(result));
//            log.info("createResponse.result{}", bulkResponse.toString());
            for (NoteSearchVo noteSearchVo : noteSearchVoList) {
                redisUtils.lLeftPush("note_index", JSON.toJSONString(noteSearchVo));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void deleteNote(String noteId) {
        try {
            User user;
            Note note=this.getById(noteId);
            NoteSearchVo noteSearchVo=ConvertUtils.sourceToTarget(note,NoteSearchVo.class);
            user = userService.getById(note.getUid());
            //懒得优化了
            List<TagNoteRelation> tagNoteRelationList = tagNoteRelationService.list(new QueryWrapper<TagNoteRelation>().eq("nid", note.getId()));
            if (tagNoteRelationList != null && !tagNoteRelationList.isEmpty()) {
                Set<String> tids = tagNoteRelationList.stream().map(TagNoteRelation::getTid).collect(Collectors.toSet());
                List<Tag> tags = tagService.listByIds(tids);
                String tagStr = tags.stream().map(Tag::getTitle).collect(Collectors.joining(","));
                noteSearchVo.setTags(tagStr);
            } else {
                noteSearchVo.setTags("");
            }

            Category category = categoryService.getById(note.getCid());
            Category parentCategory = categoryService.getById(note.getCpid());
            noteSearchVo.setUid(user.getId())
                    .setUsername(user.getUsername())
                    .setAvatar(user.getAvatar())
                    .setCategoryName(category.getTitle())
                    .setCategoryParentName(parentCategory.getTitle())
                    .setTime(note.getUpdateDate().getTime())
                    .setIsLoading(false);
            System.out.println(noteSearchVo);
            redisUtils.lRemove(NoteConstant.NOTE_INDEX,1,JSON.toJSONString(noteSearchVo));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
